#include <iostream>
#include "TractAlgorithmService.h"


TractDTO* createTractDTO(JNIEnv *env,jobject tractDTO){

	jclass cls = env->GetObjectClass(tractDTO); //or use FindClass("ru/ntcreb/csir/libs/methods/SVCH/TractDTO");
	jfieldID approximationCoefficient_K_ID = env->GetFieldID(cls, "approximationCoefficient_K", "D");
	jdouble approximationCoefficient_K = env-> GetDoubleField(tractDTO,approximationCoefficient_K_ID);

	jfieldID approximationCoefficient_N_ID = env->GetFieldID(cls, "approximationCoefficient_N", "D");
	jdouble approximationCoefficient_N = env-> GetDoubleField(tractDTO,approximationCoefficient_N_ID);

	jfieldID voltage_U0_ID = env->GetFieldID(cls, "voltage_U0", "D");
	jdouble voltage_U0 = env-> GetDoubleField(tractDTO,voltage_U0_ID);

	jfieldID stepness_S_ID = env->GetFieldID(cls, "stepness_S", "D");
	jdouble stepness_S = env-> GetDoubleField(tractDTO,stepness_S_ID);

	TractDTO* result = new TractDTO(approximationCoefficient_K,approximationCoefficient_N,voltage_U0,stepness_S);
	return result;
}

map<double,double> createTractArray(TractDTO* tract){
	map<double,double> result;

	double s = 0;
	double step = 0;
	double voltage = 0.1;
	for (int i = 0; i < MAX_ITERATIONS; i++) {
		step = abs(pow(voltage - tract->voltage_U0,
			tract->approximationCoefficient_N));

		s = pow(tract->stepness_S,
			1 / (1 + tract->approximationCoefficient_K * (step)));
		result[voltage] = s;
		voltage+=0.1;


	}
	return result;

}

map<double,double> createParallelTwoTractsArray(map<double,double> tractMap1,map<double,double> tractMap2){

	map<double,double> result; 
	map<double,double>::iterator it1;
	map<double,double>::iterator it2;
	for(it1 = tractMap1.begin(),it2 = tractMap2.begin();it1 !=tractMap1.end(),it2 !=tractMap2.end();++it1,++it2){

		result[it1->first] = it1->second + it2->second;

	}
	return result;


}

map<double,double> createConsistentTwoTractsArray(TractDTO tract1,TractDTO tract2) {

	map<double,double> result;

	for (double current=0.1; current < 0.9 ;current+=0.01) {

		double resultVoltage1 = computeVoltageConsistentTract(tract1, current);
		double resultVoltage2 = computeVoltageConsistentTract(tract2, current);
		result[current] = resultVoltage1 + resultVoltage2;
	}
	return result;
}

//must be private
double computeVoltageConsistentTract(TractDTO tract, double current) {

	double step = pow( abs((log(tract.stepness_S) - log(current))/ (tract.approximationCoefficient_K * log(current))),
		1 / tract.approximationCoefficient_N);

	//double step = pow( abs((log(abs(tract.stepness_S - current))-1)/ (tract.approximationCoefficient_K)),
	//	1 / tract.approximationCoefficient_N);

	return (step + tract.voltage_U0);

}


